home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
sprite ed
/
ing
/
ing.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
7KB
|
298 lines
/* :ts=8 bk=0
* ing.c: The next logical step in "Boing"-type display hacks.
*
* Written by Leo L. Schwab 8702.3
* Released into the public domain, but please keep the original author's
* name on it.
*
* Note: After preliminary experiments, I get the impression that this could
* somehow be faster. Suggestions appreciated.
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <math.h>
#define DEPTH 2
extern void *OpenLibrary(), *OpenWindow(), *OpenScreen(), *AllocRaster(),
*GetMsg(), *malloc();
extern long VBeamPos();
struct NewScreen scrdef = {
0, 0, 0, 0, DEPTH, /* Size filled in later */
0, 1,
HIRES,
CUSTOMSCREEN,
NULL,
NULL, /* Title filled in later */
NULL, NULL
};
struct NewWindow windef = {
0, 30, 150, 10,
-1, -1,
CLOSEWINDOW,
WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | ACTIVATE,
NULL, NULL,
"Ing!",
NULL, NULL,
0, 0, 0, 0,
WBENCHSCREEN
};
struct wlist {
struct wlist *next, *prev;
struct BitMap bitmap;
long sizx, sizy;
int maxx, maxy;
int x, y, dx, dy;
int maxdy;
};
struct Screen *scr, *wb;
struct Window *win;
struct BitMap *bm1, bm2, barmap;
struct wlist *listbase;
void *IntuitionBase, *GfxBase;
main ()
{
struct Window *wbwin;
struct ViewPort *svp;
register struct BitMap *abm;
struct BitMap *wbbm, **vbm;
register struct wlist *this = NULL;
struct wlist *new;
long wide, high, barhigh, wbhigh;
int i;
void *msg;
openstuff ();
rnd ((short) -VBeamPos());
wb = win -> WScreen; /* Workbench screen */
wbbm = wb -> RastPort.BitMap;
scrdef.LeftEdge = wb -> LeftEdge;
scrdef.TopEdge = wb -> TopEdge;
scrdef.Width = wb -> Width;
scrdef.Height = wbhigh = wb -> Height;
/* Scan all windows in workbench screen */
for (wbwin = wb -> FirstWindow; wbwin; wbwin = wbwin -> NextWindow) {
if (wbwin->Flags & BACKDROP && wbwin->Flags & WBENCHWINDOW) {
scrdef.DefaultTitle = wbwin -> ScreenTitle;
continue;
}
if (wbwin -> Height > wbhigh-21)
continue; /* too tall, no fun */
if (wbwin -> Width > wb->Width - 40)
continue; /* too wide, no fun */
/* Allocate new entry in list */
if (!(new = malloc (sizeof (*new))))
die ("malloc failed.");
new -> prev = this;
new -> next = NULL;
if (this)
this -> next = new;
listbase = new;
/* Grab necessary info */
wide = new -> sizx = wbwin -> Width;
high = new -> sizy = wbwin -> Height;
new -> maxx = wb -> Width - wide;
new -> maxy = wb -> Height - high;
new -> x = wbwin -> LeftEdge;
new -> y = wbwin -> TopEdge;
new -> dx = new -> dy = 0;
/*
* Compute maximum initial vertical velocity.
* (Do you know how long it took me to arrive at this
* formula?)
* Note: If gravity is anything other than one, this
* formula falls apart.
*/
new -> maxdy = sqrt (2 * new->maxy + 0.25) - 0.5 + 1.0;
/* Create bitmap and copy window into it */
InitBitMap (&new -> bitmap, (long) DEPTH, wide, high);
for (i=0; i<DEPTH; i++)
if (!(new -> bitmap.Planes[i] = AllocRaster (wide, high)))
die ("AllocRaster failed.");
WindowToFront (wbwin); /* WindowToFront() doesn't happen */
Delay (5L); /* immediately, so wait. */
BltBitMap
(wbbm, (long) wbwin -> LeftEdge, (long) wbwin -> TopEdge,
&new -> bitmap, 0L, 0L,
wide, high, 0xC0L, 0xffL, NULL);
this = new;
}
/* All windows scanned and copied, now to do the hard part */
scr = OpenScreen (&scrdef); /* Clone WorkBench */
bm1 = scr -> ViewPort.RasInfo -> BitMap;
svp = &scr -> ViewPort;
/* Make second set of bitplanes for double buffering */
wide = wb -> Width;
InitBitMap (&bm2, (long) DEPTH, wide, wbhigh);
for (i=0; i<DEPTH; i++)
if (!(bm2.Planes[i] = AllocRaster (wide, wbhigh)))
die ("AllocRaster 2 failed.");
BltBitMap
(bm1, 0L, 0L, &bm2, 0L, 0L, wide, wbhigh, 0xc0L, 0xffL, NULL);
/* Create private bitmap to hold screen title bar */
barhigh = wb -> BarHeight;
InitBitMap (&barmap, (long) DEPTH, wide, barhigh);
for (i=0; i<DEPTH; i++)
if (!(barmap.Planes[i] = AllocRaster (wide, barhigh)))
die ("AllocRaster 3 failed.");
BltBitMap
(bm1, 0L, 0L, &barmap, 0L, 0L, wide, barhigh, 0xc0L, 0xffL, NULL);
i = 0;
vbm = &scr -> ViewPort.RasInfo -> BitMap;
abm = &bm2;
while (1) {
/* Copy screen bar */
BltBitMap (&barmap, 0L, 0L,
abm, 0L, 0L,
wide, barhigh, 0xc0L, 0xffL, NULL);
/* Clear rest of screen */
BltBitMap (abm, 0L, 0L,
abm, 0L, barhigh,
wide, wbhigh-barhigh, 0L, 0xffL, NULL);
/* Scan window copies backwards */
for (this = listbase; this; this = this -> prev) {
if ((this -> x += this -> dx) > this -> maxx) {
this -> x = this->maxx * 2 - this->x;
this -> dx = -this -> dx;
} else if (this -> x < 0) {
this -> x = -this -> x;
this -> dx = -this -> dx;
}
if ((this -> y += this -> dy) > this -> maxy) {
this -> y = this -> maxy;
this -> dy = -rnd (this->maxdy - 4) - 4;
this -> dx = rnd (31) - 15;
} else
this -> dy++;
/* Copy window image */
BltBitMap
(&this -> bitmap, 0L, 0L,
abm, (long) this -> x, (long) this -> y,
this -> sizx, this -> sizy, 0xc0L, 0xffL, NULL);
}
/*
* This is the hairy part. I've tried to arrange things so
* that there will be a minimum of hashing, but under certain
* phases of the moon, it's unavoidable. Sorry.
*/
Forbid ();
if (i) { /* Ping */
*vbm = bm1;
abm = &bm2;
} else { /* Pong */
*vbm = &bm2;
abm = bm1;
}
i = !i;
/* Surprise! Intuition doesn't mind this! */
ScrollVPort (svp);
Permit ();
if (msg = GetMsg (win -> UserPort)) {
ReplyMsg (msg);
break;
}
WaitTOF ();
}
/* Restore the original */
Forbid ();
*vbm = bm1;
ScrollVPort (svp); /* Ping! */
Permit ();
closestuff ();
}
openstuff ()
{
if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
printf ("Intuition missing.\n");
exit (100);
}
if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) {
printf ("Art shop closed.\n");
closestuff ();
exit (100);
}
if (!(win = OpenWindow (&windef))) {
printf ("Window painted shut.\n");
closestuff ();
exit (100);
}
}
die (str)
char *str;
{
puts (str);
closestuff ();
exit (100);
}
closestuff ()
{
register int i;
for (i=0; i<DEPTH; i++) {
if (barmap.Planes[i])
FreeRaster (barmap.Planes[i],
(long) wb->Width, (long) wb->BarHeight);
if (bm2.Planes[i])
FreeRaster (bm2.Planes[i],
(long) wb->Width, (long) wb->Height);
}
if (listbase) freelist ();
if (scr) CloseScreen (scr);
if (win) CloseWindow (win);
if (GfxBase) CloseLibrary (GfxBase);
if (IntuitionBase) CloseLibrary (IntuitionBase);
}
freelist ()
{
register struct wlist *this = listbase, *tmp;
register int i;
while (this) {
for (i=0; i<DEPTH; i++)
if (this -> bitmap.Planes[i])
FreeRaster (this -> bitmap.Planes[i],
this -> sizx, this -> sizy);
tmp = this;
this = this -> prev;
free (tmp);
}
}